package com.sh.data.engine.common.util;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 时间通用转换
 */
@Slf4j
public class DateUtil {
    /**
     * 默认的格式
     */
    public static String formatDate(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * @deprecated 建议使用DateUtil.format(Date, DATE_PATTERN)
     */
    @Deprecated
    public static String formatDate(Date date, String format) {
        DateFormat dateFormat = new SimpleDateFormat(format);
        return date == null ? null : dateFormat.format(date);
    }

    @SneakyThrows
    public static Date parse(String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date parse = simpleDateFormat.parse(format);
        return parse;
    }

    public static String formatDate(long time, String format) {
        DateFormat dateFormat = new SimpleDateFormat(format);
        return time == 0 ? null : dateFormat.format(new Date(time));
    }

    public static Long toLong(String date) {
        return toLong(date, DATE_PATTERN.yyyyMMddHHmmss);
    }

    /**
     * 时间字符串转long类型
     */
    public static Long toLong(String date, DATE_PATTERN format) {
        Date parse1 = DateUtil.parse(date, format);
        return parse1.getTime();
    }

    /**
     * @deprecated 建议使用 DateUtil.parse(String, DATE_PATTERN)
     */
    @Deprecated
    public static Date toDate(String date, String format) {
        DateFormat dateFormat = new SimpleDateFormat(format);
        try {
            return dateFormat.parse(date);
        } catch (ParseException e) {
            log.error("时间转换失败", e);
        }
        return null;
    }

    /**
     * 返回当前日期的 想个的某一时刻的时间，amount为正数 当前时间后的时间， 为负数 当前时间前的时间
     *
     * @param d      ,某一个日期
     * @param field  日历字段 y 年 M 月 d 日 H 时 m 分 s 秒
     * @param amount 数量
     * @return 一个日期
     */
    public static Date getPerDate(Date d, String field, int amount) {
        if (StringUtils.isBlank(field)) {
            return null;
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);

        switch (field) {
            case "y":
                calendar.add(Calendar.YEAR, amount);
                break;
            case "M":
                calendar.add(Calendar.MONTH, amount);
                break;
            case "d":
                calendar.add(Calendar.DAY_OF_MONTH, amount);
                break;
            case "H":
                calendar.add(Calendar.HOUR, amount);
                break;
            case "m":
                calendar.add(Calendar.MINUTE, amount);
                break;
            case "s":
                calendar.add(Calendar.SECOND, amount);
                break;
            default:
                break;
        }

        return calendar.getTime();
    }

    /**
     * 今天开始时间
     */
    public static Date getTodayStart(Date date) {
        Calendar todayStart = Calendar.getInstance();
        todayStart.setTime(date);
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    /**
     * 某某天开始
     */
    public static Date getSomeDayStart(Date date, Integer index) {
        Calendar todayStart = Calendar.getInstance();
        todayStart.setTime(date);
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        todayStart.add(Calendar.DAY_OF_MONTH, index);
        return todayStart.getTime();
    }

    public static Date getSomeMonthStart(Date date, Integer index) {
        Calendar todayStart = Calendar.getInstance();
        todayStart.setTime(date);
        todayStart.add(Calendar.MONTH, index);
        Date time = todayStart.getTime();
        return time;
    }

    /**
     * 某某天结束
     */
    public static Date getSomeDayEnd(Date date, Integer index) {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.setTime(date);
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 0);
        todayEnd.add(Calendar.DAY_OF_MONTH, index);
        return todayEnd.getTime();
    }

    /**
     * 今天结束时间
     */
    public static Date getTodayEnd(Date date) {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.setTime(date);
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 0);
        return todayEnd.getTime();
    }

    /**
     * long型时间戳转
     */
    public static Date getDateBySeconds(Long seconds) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String d = format.format(Long.valueOf(seconds + "000"));
        Date date = null;
        try {
            date = format.parse(d);
        } catch (ParseException e) {
            log.error("获取日期失败");
        }
        return date;
    }

    /**
     * String(yyyy-MM-dd)转当天结束时间String(yyyy-MM-dd HH:mm:ss)
     */
    public static String getTodayEnd(String startEnd) {
        if (StringUtils.isBlank(startEnd)) {
            return StringUtils.EMPTY;
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            date = format.parse(startEnd);
        } catch (ParseException e) {
            log.error("获取日期失败");
        }
        Date todayEnd = getTodayEnd(date);

        return format2.format(todayEnd);
    }

    /**
     * 日期的文本格式
     */
    public enum DATE_PATTERN {
        yyyyMMdd("yyyy-MM-dd"),
        yyyyMMddHHmmss("yyyy-MM-dd HH:mm:ss"),
        yyyyMMddHHmmssStr("yyyyMMddhhmmss");

        DATE_PATTERN(String pattern) {
            this.pattern = pattern;
            this.threadLocal = ThreadLocal.withInitial(() -> new SimpleDateFormat(this.pattern));
        }

        private final String pattern;
        private final ThreadLocal<SimpleDateFormat> threadLocal;
    }

    public static Date parse(String dateStr, DATE_PATTERN datePattern) {
        try {
            return datePattern.threadLocal.get().parse(dateStr);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String format(Date date, DATE_PATTERN datePattern) {
        return datePattern.threadLocal.get().format(date);
    }

    public static Date addDays(String date, Integer amount) {
        try {
            final Date orginDate = DATE_PATTERN.yyyyMMdd.threadLocal.get().parse(date);

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(orginDate);
            calendar.add(Calendar.DATE, amount);
            return calendar.getTime();
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long ns = 1000;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒
        long sec = diff % nd % nh % nm / ns;
        // 输出结果
        return day + "天" + hour + "小时" + min + "分钟" + sec + "秒";
    }

    public static String getMonthNumByEn(String monthEnName) {
        String month = "";
        switch (monthEnName) {
            case "Jan":
                month = "01";
                break;
            case "Feb":
                month = "02";
                break;
            case "Mar":
                month = "03";
                break;
            case "Apr":
                month = "04";
                break;
            case "May":
                month = "05";
                break;
            case "Jun":
                month = "06";
                break;
            case "Jul":
                month = "07";
                break;
            case "Aug":
                month = "08";
                break;
            case "Sept":
                month = "09";
                break;
            case "Oct":
                month = "10";
                break;
            case "Nov":
                month = "11";
                break;
            case "Dec":
                month = "12";
                break;
        }
        return month;
    }
}

